ROUND_NO = 0
ROUND_START = 1
ROUND_PLAY = 2
ROUND_END = 3

GM.Round = ROUND_NO

function GM:NewRound()
	self.Round = ROUND_START
	timer.Simple(25, function() self.Round = ROUND_PLAY end)

	-- Cleanup
	for _, ent in pairs( ents.FindByClass( "weapon_*" ) ) do
		if ent:IsValid() then
			ent:Remove()
		end
	end
	for _, ent in pairs( ents.FindByClass( "prop_ragdoll" ) ) do
		if ent:IsValid() then
			ent:Remove()
		end
	end

	-- Reload
	if self.MapFile then
		for _, entt in pairs(self.MapFile.weapons) do
			entt = string.Explode(" ", entt)
			local ent = ents.Create(entt[1])
			ent:SetPos(Vector(entt[2], entt[3], entt[4]))
			ent:Spawn()
			ent:Activate()
		end
	end

	-- Respawn breakables
	for _, ent in pairs( ents.GetAll() ) do
		if ent:IsValid() and ent.RndRemove then
			ent:Remove()
		end
	end
	for _,tab in pairs(self.BrkTbl) do
		local ent = ents.Create(tab.Class)
		ent:SetPos(tab.Pos)
		ent:SetAngles(tab.Angle)
		if tab.Model then
			ent:SetModel(tab.Model)
		end
		for _,v in pairs(tab.K) do
			ent:SetKeyValue(v[1],v[2])
		end
		ent:Spawn()
		ent:Activate()
		ent.RndRemove = true
	end

	for _,pl in pairs(player.GetAll()) do
		if pl:Team() == TEAM_GUARD_DEAD then
			pl:SetTeam(TEAM_GUARD)
		elseif pl:Team() == TEAM_PRISONER_DEAD then
			pl:SetTeam(TEAM_PRISONER)
		end
	end
	-- AutoSwap
	local G = team.NumPlayers(TEAM_GUARD)
	local P = team.NumPlayers(TEAM_PRISONER)
	if P > 2*G then
		for k,v in pairs(self.PSwap) do
			if v and v:IsValid() then
				v:SetTeam(TEAM_GUARD)
				P = P - 1
				G = G + 1
				local rp = RecipientFilter()
				rp:AddPlayer(v)
				umsg.Start("WishSwap", rp)
				umsg.Bool(false)
				umsg.End()
			end
			table.remove(self.PSwap, k)
			if not ( P > 2*G ) then break end
		end
		while P > 2*G+1 do
			local ply = team.GetPlayers(TEAM_PRISONER)[math.random(1, P)]
			ply:SetTeam(TEAM_GUARD)
			P = P - 1
			G = G + 1
		end
	elseif P < 2*G then
		for k,v in pairs(self.GSwap) do
			if v and v:IsValid() then
				v:SetTeam(TEAM_PRISONER)
				P = P + 1
				G = G - 1
				local rp = RecipientFilter()
				rp:AddPlayer(v)
				umsg.Start("WishSwap", rp)
				umsg.Bool(false)
				umsg.End()
			end
			table.remove(self.GSwap, k)
			if not ( P < 2*G ) then break end
		end
		while P+1 < 2*G do
			local ply = team.GetPlayers(TEAM_GUARD)[math.random(1, G)]
			ply:SetTeam(TEAM_PRISONER)
			P = P + 1
			G = G - 1
		end
	end
	for k,plP in pairs(self.PSwap) do
		if #(self.GSwap) == 0 then break end
		if plP and plP:IsValid() then
			local plG = nil
			for k,pl in pairs(self.GSwap) do
				if pl and pl:IsValid() then
					plG = pl
					break
				else
					table.remove(self.GSwap, k)
				end
			end
			if plG then
				plP:SetTeam(TEAM_GUARD)
				plG:SetTeam(TEAM_PRISONER)
				local rp = RecipientFilter()
				rp:AddPlayer(plP)
				rp:AddPlayer(plG)
				umsg.Start("WishSwap", rp)
				umsg.Bool(false)
				umsg.End()
			end
		else
			table.remove(self.PSwap, k)
		end
	end

	-- Respawn
	for _, pl in pairs( player.GetAll() ) do
		if pl:IsValid() and pl:Team() != TEAM_SPECTATOR then
			pl:Spawn()
			pl:SetCollisionGroup(1)
		end
	end
	timer.Simple(20, function()
		for _, pl in pairs( player.GetAll() ) do
			if pl:IsValid() and pl:Team() != TEAM_SPECTATOR then
				pl:SetCollisionGroup(5)
			end
		end
	end)
end

function GM:EndRound(win)
	self.Round = ROUND_END
	if not win then
		for _, pl in pairs(player.GetAll()) do
			pl:ChatPrint( "Gardiens - "..team.GetScore(TEAM_GUARD).." | Prisonniers - "..team.GetScore(TEAM_PRISONER) )
			pl:ChatPrint( "Prochain round dans 5 secondes." )
		end
		timer.Simple(5, self.NewRound, self)
		return
	end
	if win > 0 then
		team.AddScore(win, 1) end
	local txt = ""
	if win == TEAM_GUARD then
		txt = "Les Gardiens remportent le round."
	else
		txt = "Les Prisonniers remportent le round."
	end
	local txt2 = "Guards - "..team.GetScore(TEAM_GUARD).." | Prisoners - "..team.GetScore(TEAM_PRISONER)
	for _, pl in pairs(player.GetAll()) do
		pl:PrintMessage( HUD_PRINTCENTER, txt )
		pl:ChatPrint( txt )
		pl:ChatPrint( txt2 )
	end
	local NM = self.NextMap
	local Sc = self.Rounds:GetInt()
	if NM and Sc > 0 then
		if team.GetScore(TEAM_GUARD) >= Sc or team.GetScore(TEAM_PRISONER) >= Sc then
			for _, pl in pairs(player.GetAll()) do
				pl:ChatPrint( "Changement de map pour "..NM.."dans 10 secondes" )
			end
			return timer.Simple(10, game.ConsoleCommand, "changelevel "..NM.."\n")
		end
	end
	for _, pl in pairs(player.GetAll()) do
		pl:ChatPrint( "Prochain round dans 5 secondes." )
	end
	timer.Simple(5, self.NewRound, self)
end

local function PlayerDeath()
	local GM = gmod.GetGamemode()
	if GM.Round == ROUND_END then return end
	local G = team.NumPlayers(TEAM_GUARD)
	local P = team.NumPlayers(TEAM_PRISONER)
	if G > 0 and P == 0 then GM:EndRound(TEAM_GUARD)
	elseif G == 0 and P > 0 then GM:EndRound(TEAM_PRISONER) end
	if G == 0 and P == 0 then GM:EndRound() end
end
hook.Add( "PlayerDeath", "GJail_PlayerDeath", PlayerDeath )